// 封装axios

import axios from 'axios'

// 导入vuex仓库
import store from '@/store'

// 导入路由
import router from '@/router'

// 导入Toast
import { Toast } from 'vant'
console.log(router)

// 通过axios的create方法来创建axios的实例对象，并配置
const instance = axios.create({
  // 跟地址
  baseURL: 'http://toutiao.itheima.net',
  timeout: 10000
})

// 添加请求拦截器 ==> 记得将axios 换成 instance
instance.interceptors.request.use(
  function(config) {
    // 在发送请求之前做些什么 ==> 在请求头的headers中带上token 信息
    const token = store.state.user.token.token

    // token 存在的时候，才带过去
    if (token) {
      // 有token
      config.headers.Authorization = `Bearer ${token}`
    }
    // console.log('请求拦截器的config配置对象 ', config)

    return config
  },
  function(error) {
    // 对请求错误做些什么
    return Promise.reject(error)
  }
)

// 添加响应拦截器
instance.interceptors.response.use(
  function(response) {
    // 对响应数据做点什么 ==> 响应是成功的
    // console.log('响应拦截器的response ', response)

    // return response
    // 在组件中发送请求得到的结果就可以少写一层data
    return response.data
  },
  async function(error) {
    // 对响应错误做点什么 ==> 响应失败
    console.dir(error)

    // 判断响应的状态码 status 是否为401（token过期了） ==> 就需要跳转到登录login重新登录
    if (error.response.status === 401) {
      // 1. 清除过期的token
      // store.commit('mutations方法')
      // store.dispatch('actions方法')
      // store.commit('user/removeToken')
      // 2.
      // router.push('/login') 没有带上回来的路
      // 获取当前路由信息
      // 在vue组件中 this.$route
      // js模块中，通过 router.currentRoute
      // console.log(router.currentRoute)
      /* router.push({
        path: '/login',
        query: {
          // 回来的路
          back: router.currentRoute.fullPath
        }
      }) */
      // 开始实现无感刷新
      // 1. 获取refresh_token ==> 通过vuex来获取

      const refreshToken = store.state.user.token.refresh_token
      console.log(refreshToken)

      if (refreshToken) {
        // 有刷新token ==> 使用刷新token去发送请求来获取到新的token

        // 坑：注意这次请求使用axios来放松请求，不能使用instance来发送请求
        //  因为instance之前有配置过请求拦截器（每次请求会带上token，这次请求token是过期的，是需要带上刷新token）
        // axios没有配置过根路径，所有需要早url上带上完整的跟地址
        try {
          const res = await axios({
            url: 'http://toutiao.itheima.net/v1_0/authorizations',
            method: 'PUT',
            headers: {
              // 需要在请求头中带上 Authorization ，带上刷新token
              Authorization: `Bearer ${refreshToken}`
            }
          })
          // console.log(res)

          // 获取到了新的token，给存储起来（vuex + 本地存储） ==> 仓库 setToken方法
          // error ==> 以下写法只是存储了token令牌信息，没有存储起来 refresh_token
          // store.commit('user/setToken', res.data.data.token)

          // 目标： token + refresh_token
          // store.commit('user/setToken', { token: 获取到的新的token, refresh_token })

          store.commit('user/setToken', {
            token: res.data.data.token,
            refresh_token: refreshToken
          })

          // 在发一次之前的请求
          // instance ==> 根路径的配置 + 请求拦截器（带上token，是获取到的新token）
          // error.config 之前请求的相关配置信息
          return instance(error.config)
        } catch (e) {
          // 走到这，说明刷新token也过期了，新的token请求失败了
          goLogin()
        }
      } else {
        // 没有刷新token
        goLogin()
      }
    } else {
      // 非401的情况 ==> 不是token过期了
      return Promise.reject(error)
    }
  }
)

// 导出axios的实例
export default instance

function goLogin() {
  // 1. 删除token
  store.commit('user/removeToken')

  // 2. 跳转去登录
  router.push({
    path: '/login',
    query: {
      // 回来的路
      back: router.currentRoute.fullPath
    }
  })

  // 3. 提示  this.$toast 组件中使用，在单独的js模块中可以单独导入Toast
  Toast.fail('登录过期，请重新登录')
}
